package com.isesol.arch.common.utils;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

/**
 * 工作流工具类
 */
public class RestUtil {

    private static Logger logger = LoggerFactory.getLogger(RestUtil.class);

    /**
     * 使用Base64的方式加密用户名和密码
     * 必须提供用户名和系统ID否则REST服务拒绝服务请求
     * @return
     */
    public static HttpHeaders createHeaders(){
        return new HttpHeaders();
    }

    /**
     * 从REST服务获取数据
     * @param resourceUrl   REST服务资源路径，例如查询任务列表：/runtime/tasks
     * @param params        URL参数列表
     * @param method        HTTP请求方法类型
     * @param resultType    请求结果的数据类型，会自动封装
     * @return
     */
    public static <E> E sendRestRequest(String resourceUrl, Map<String, String> params,
                                  HttpMethod method, Class<E> resultType) {
        RestTemplate restTemplate = createRestTemplate();
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(RestUtil.createHeaders());
        logger.error("url:{}", resourceUrl);
        String url = WebUtils.mapToQueryString(resourceUrl, params);
        System.out.println(url);
        ResponseEntity<E> exchange = restTemplate.exchange(url, method, requestEntity, resultType);
        return exchange.getBody();
    }

    public static RestTemplate createRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        messageConverters.add(new StringHttpMessageConverter());
        return restTemplate;
    }

    /**
     * 从REST服务获取数据（无查询参数）
     * @param resourceUrl   REST服务资源路径，例如查询任务列表：/runtime/tasks
     * @param method        HTTP请求方法类型
     * @param resultType    请求结果的数据类型，会自动封装
     * @return
     */
    public static <E> E sendRestRequest(String resourceUrl, HttpMethod method, Class<E> resultType) {
        return sendRestRequest(resourceUrl, null, method, resultType);
    }

    /**
     * 发送JSON请求（默认使用POST）
     * @param resourceUrl   REST服务资源路径，例如查询任务列表：/runtime/tasks
     * @param urlParams     URL参数
     * @param jsonParams    HTTP body的JSON
     * @param resultType    请求结果的数据类型，会自动封装
     * @return
     */
    public static <E> E sendJson(String resourceUrl, Map<String, String> urlParams,
                                    Object jsonParams, Class<E> resultType) {
        HttpHeaders headers = RestUtil.createHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(jsonParams, headers);

        String url = WebUtils.mapToQueryString(resourceUrl, urlParams);
        RestTemplate restTemplate = createRestTemplate();
        ResponseEntity<E> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, resultType);
        return exchange.getBody();
    }

    /**
     * 发送JSON请求（默认使用POST）
     * @param resourceUrl   REST服务资源路径，例如查询任务列表：/runtime/tasks
     * @param urlParams     URL参数
     * @param jsonParams    HTTP body的JSON
     * @param resultType    请求结果的数据类型，会自动封装
     * @return
     */
    public static <E> ResponseEntity<E> sendJsonForResponseEntity(String resourceUrl, Map<String, String> urlParams,
                                                                  Object jsonParams, Class<E> resultType) {
        return sendJsonForResponseEntity(resourceUrl, HttpMethod.POST, urlParams, jsonParams, resultType);
    }

    /**
     * 发送JSON请求（默认使用POST）
     * @param resourceUrl   REST服务资源路径，例如查询任务列表：/runtime/tasks
     * @param urlParams     URL参数
     * @param jsonParams    HTTP body的JSON
     * @param resultType    请求结果的数据类型，会自动封装
     * @return
     */
    public static <E> ResponseEntity<E> sendJsonForResponseEntity(String resourceUrl, HttpMethod method, Map<String, String> urlParams,
                                                                  Object jsonParams, Class<E> resultType) {
        HttpHeaders headers = RestUtil.createHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(jsonParams, headers);

        String url = WebUtils.mapToQueryString(resourceUrl, urlParams);
        RestTemplate restTemplate = createRestTemplate();
        ResponseEntity<E> exchange = restTemplate.exchange(url, method, requestEntity, resultType);
        return exchange;
    }

    /**
     * 判断状态码是否为成功类型
     * @param statusCode
     * @return
     */
    public static boolean isOk(HttpStatus statusCode) {
        return statusCode == HttpStatus.OK || statusCode == HttpStatus.CREATED || statusCode == HttpStatus.NO_CONTENT;
    }
}